feat(connectors): database selector + per-card write toggle (#568) - #633
Conversation
|
Caution Review failedPull request was closed or merged during review WalkthroughThis PR implements per-card database selection and write-permission toggles. It adds Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Editor as Widget Editor
participant Store as Widget Store
participant API as /api/connections/{id}/databases
participant DBModule as Connection Module
User->>Editor: Select connection in widget editor
Editor->>Store: setConnectionId(id)
activate Store
Store->>Store: Clear database override
deactivate Store
User->>Editor: View database selector
Editor->>API: GET /api/connections/{id}/databases
activate API
API->>DBModule: listDatabases(credentials)
DBModule-->>API: [db1, db2, ...]
API-->>Editor: { data: { databases: [...] } }
deactivate API
Editor->>Editor: Render dropdown with options
User->>Editor: Select database
Editor->>Store: setDatabase(selected)
activate Store
Store->>Store: Update database field
deactivate Store
Editor->>Store: Get database value
Editor->>Store: Get allowWrites value
Store-->>Editor: { database, allowWrites }
Editor->>Editor: Save widget with overrides
sequenceDiagram
participant Client as Client/Widget
participant QueryAPI as POST /api/query/write
participant DB as Database
participant Dashboard as Dashboard Store
Client->>QueryAPI: POST { connectionId, query, widgetId, dashboardId }
activate QueryAPI
QueryAPI->>Dashboard: Load dashboard by dashboardId
Dashboard-->>QueryAPI: DashboardRow
QueryAPI->>QueryAPI: Find widget in layoutJson
alt Widget not found or allowWrites false
QueryAPI-->>Client: 403 Forbidden
else Widget found and allowWrites true
QueryAPI->>QueryAPI: Check widget.connectionId matches
alt Mismatch
QueryAPI-->>Client: 403 Forbidden
else Match
QueryAPI->>QueryAPI: Apply database override if widget.database provided
QueryAPI->>DB: Execute query with credentials
DB-->>QueryAPI: Result
QueryAPI-->>Client: 200 { data }
end
end
deactivate QueryAPI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
Add database introspection to connectors (listDatabases for Neo4j/PG, listSchemas for PG) with graceful fallback. Introduce per-widget write mode toggle in Advanced tab and per-card database override in widget editor. Server enforces allowWrites by looking up the widget in the dashboard layout before executing write queries. - connection/: abstract listDatabases(), Neo4j SHOW DATABASES with fallback, PG pg_database + information_schema.schemata - API: GET /connections/[id]/databases, POST /connections/list-databases-inline - Schema: allow_per_card_db on connections, database + allowWrites on DashboardWidget - Write route: when widgetId + dashboardId provided, verifies widget.allowWrites; legacy form-widget path (no widgetId) still works with user-level canWrite - Widget editor: database dropdown (Data tab), write mode toggle (Advanced tab) - 26 new tests (10 connector integration, 11 API route, 5 write enforcement) Closes #568 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add database to widget-query cache key to prevent cross-DB collisions - Forward full config (SSL, timeouts) in list-databases-inline route - Validate widget-connection binding and gate DB override by allowPerCardDb in write route - Return allowPerCardDb from POST /api/connections - Show placeholder in DatabaseSelector when no databases available - Clear database override when switching connections in store - Exclude information_schema and escape underscore in PG listSchemas - Hide write mode checkbox for content-only widgets (markdown/iframe) - Only persist database/allowWrites for non-content-only widgets - Add 3 tests: per-card DB propagation, DB override gating, widget-connection mismatch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ides Cover DatabaseSelector component (loading, empty, select, __default__ mapping), useConnectionDatabases hook (query key, enabled/disabled, fetch endpoint), and per-card database override logic in the query route (allowPerCardDb true/false/undefined, missing database field). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ase fields - Add listDatabases tests: returns databases, correct credentials forwarding - Add listSchemas tests: returns schemas, empty array when unsupported - Add widget-editor-store tests: database/allowWrites defaults, setters, setConnectionId clears database, resetForAdd clears both Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Forward full validated config in list-databases-inline (not partial) - Strengthen DB override test: assert connection-level database preserved - Add legacy widget test: missing allowWrites defaults to 403 - Add loadFromWidget hydration tests for database/allowWrites fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add listDatabases/listSchemas to module-level mock factory so TypeScript accepts the return type when overriding in tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e24c046 to
ec9d06c
Compare
|



Summary
Recreated from #631 to fix CI trigger after base branch change.
Closes #568
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit